import CryptoJS from 'crypto-js'
const DES_KEY = 'htdata2018',
  DES_IV = '00000000'
/***
 * 将任意数量对象或者字符串传入该方法，若有任意一个为空，则返回true
 * 可判断 空对象 空数组 空字符串 undefined null
 * @returns {boolean}
 */
export function isEmpty() {
  let len = arguments.length
  if (len === 0) {
    return true
  }
  for (let i = 0; i < len; i++) {
    let a = arguments[i]
    if (typeof a === 'undefined' || a == null || (typeof a === 'string' && a.trim() === '')) {
      return true
    } else if (Object.prototype.toString.call(a) === '[object Array]') {
      if (a.length === 0) {
        return true
      }
    } else if (Object.prototype.toString.call(a) === '[object Object]') {
      if (Object.keys(a).length === 0) {
        return true
      }
    }
  }
  return false
}

export function isFunction(fn) {
  return typeof fn === 'function' && typeof fn.nodeType !== 'number'
}

export function isPlainObject(obj) {
  let proto,
    Ctor,
    class2type = {},
    toString = class2type.toString,
    hasOwn = class2type.hasOwnProperty,
    fnToString = hasOwn.toString,
    ObjectFunctionString = fnToString.call(Object)
  if (!obj || toString.call(obj) !== '[object Object]') {
    return false
  }
  proto = Object.getPrototypeOf(obj)
  if (!proto) {
    return true
  }
  Ctor = hasOwn.call(proto, 'constructor') && proto.constructor
  return typeof Ctor === 'function' && fnToString.call(Ctor) === ObjectFunctionString
}

export function isInteger(obj) {
  return typeof obj === 'number' && obj % 1 === 0
}

export function getMd5EncodeString(data) {
  return CryptoJS.MD5(data).toString()
}

export function getDESEncodeString(data, key, iv) {
  key = isEmpty(key) ? DES_KEY : key
  iv = isEmpty(iv) ? DES_IV : iv
  let _key = CryptoJS.enc.Utf8.parse(key)
  let _iv = CryptoJS.enc.Utf8.parse(iv)
  let encrypted = CryptoJS.DES.encrypt(data, _key, {
    iv: _iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  return encrypted.toString()
}

export function getDESDecodeString(data, key, iv) {
  key = isEmpty(key) ? DES_KEY : key
  iv = isEmpty(iv) ? DES_IV : iv
  let _key = CryptoJS.enc.Utf8.parse(key)
  let _iv = CryptoJS.enc.Utf8.parse(iv)
  let decrypted = CryptoJS.DES.decrypt(data, _key, {
    iv: _iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  return decrypted.toString(CryptoJS.enc.Utf8)
}

/***
 * 检测密码强度
 */
export function checkStrong(sValue) {
  let level = 0
  if (sValue.length < 6) return level
  // 数字
  if (/\d/.test(sValue)) level++
  // 小写
  if (/[a-z]/.test(sValue)) level++
  // 大写
  if (/[A-Z]/.test(sValue)) level++
  // 特殊字符
  if (/\W/.test(sValue)) level++
  // 逻辑处理
  if (level >= 3) {
    level = sValue.length < 12 ? 3 : 4
  }
  return level
}

/***
 * 批量修改对象中日期格式，将时间戳修改为日期字符串
 * item为对象，keys为对象中需要修改的key，format为日期格式
 */
export function dateToString(item, keys, format) {
  format = isEmpty(format) ? 'yyyy-MM-dd HH:mm:ss' : format
  for (let i = 0; i < keys.length; i++) {
    if (!isEmpty(item[keys[i]])) {
      item[keys[i]] = new Date(item[keys[i]]).format(format)
    }
  }
}

export function stringToInt(item, keys) {
  for (let i = 0; i < keys.length; i++) {
    if (!isEmpty(item[keys[i]])) {
      item[keys[i]] = parseInt(item[keys[i]])
    }
  }
}

/***
 * 批量修改对象中数字格式，将数字修改为金额格式
 * item为对象，keys为对象中需要修改的key，n为小数点保留位数
 */
export function numberFormat(item, keys, n) {
  n = isEmpty(n) ? '2' : n
  for (let i = 0; i < keys.length; i++) {
    let num = item[keys[i]]
    n = n > 0 && n <= 20 ? n : 2
    num = parseFloat((num + '').replace(/[^\d.-]/g, '')).toFixed(n) + ''
    let l = num.split('.')[0].split('').reverse(),
      r = num.split('.')[1],
      t = ''
    for (let j = 0; j < l.length; j++) {
      t += l[j] + ((j + 1) % 4 === 0 && j + 1 !== l.length ? ',' : '')
    }
    item[keys[i]] = t.split('').reverse().join('') + '.' + r
  }
}

/**
 * 格式化文件大小, 输出成带单位的字符串
 * @param {Number} size 文件大小
 * @param {Number} [pointLength=2] 精确到的小数点数。
 * @param {Array} [units=[ 'B', 'KB', 'MB', 'GB', 'TB' ]] 单位数组。从字节，到千字节，一直往上指定。
 * 如果单位数组里面只指定了到了KB(千字节)，同时文件大小大于MB, 此方法的输出将还是显示成多少K.
 */
export function formatSize(size, pointLength, units) {
  let unit
  units = units || ['B', 'KB', 'MB', 'GB', 'TB']
  while ((unit = units.shift()) && size > 1024) {
    size = size / 1024
  }
  return (unit === 'B' ? size : size.toFixed(pointLength === undefined ? 2 : pointLength)) + unit
}

export function checkIDCard(rule, value, callback) {
  setTimeout(function () {
    if (!value) {
      return callback(new Error('请输入身份证号码'))
    }
    let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
    if (reg.test(value) === false) {
      return callback(new Error('输入的身份证号码无效'))
    }
    callback()
  }, 200)
}

export function checkPhone(rule, value, callback) {
  setTimeout(function () {
    if (rule.required && !value) {
      return callback(new Error('请输入手机号码'))
    }
    if (value) {
      let reg = /^1[0-9]{10}$/
      if (reg.test(value) === false) {
        return callback(new Error('输入的手机号码无效'))
      }
    }
    callback()
  }, 200)
}

export function checkEmail(rule, value, callback) {
  setTimeout(function () {
    if (rule.required && !value) {
      return callback(new Error('请输入邮箱'))
    }
    if (value) {
      let reg = /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/
      if (reg.test(value) === false) {
        return callback(new Error('输入的邮箱无效'))
      }
    }
    callback()
  }, 200)
}

export function checkUsername(rule, value, callback) {
  setTimeout(function () {
    let reg_first = /^[a-zA-Z_-]$/,
      reg = /^[a-zA-Z_-]([a-zA-Z0-9_.-]){4,19}$/
    if (!value) {
      return callback(new Error('请输入用户名'))
    } else if (reg_first.test(value.substr(0, 1)) === false) {
      return callback(new Error('请输入以a-zA-Z_-开头的内容'))
    } else if (value.length < 5) {
      return callback(new Error('用户名最小长度为5'))
    } else if (value.length > 20) {
      return callback(new Error('用户名最大长度为20'))
    } else if (reg.test(value) === false) {
      return callback(new Error('输入内容只能包含a-zA-Z0-9_.-'))
    }
    callback()
  }, 200)
}

export function checkLoginName(rule, value, callback) {
  setTimeout(function () {
    let reg = /^([a-zA-Z0-9_.-]){5,20}$/
    if (!value) {
      return callback(new Error('请输入用户名'))
    } else if (value.length < 5) {
      return callback(new Error('用户名最小长度为5'))
    } else if (value.length > 20) {
      return callback(new Error('用户名最大长度为20'))
    } else if (reg.test(value) === false) {
      return callback(new Error('输入内容只能包含a-zA-Z0-9_.-'))
    }
    callback()
  }, 200)
}

export function checkIPAddress(rule, value, callback) {
  setTimeout(function () {
    if (rule.required && !value) {
      return callback(new Error('请输入IP地址'))
    }
    if (value) {
      let reg = /((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))/
      if (reg.test(value) === false) {
        return callback(new Error('输入的IP地址无效'))
      }
    }
    callback()
  }, 200)
}

export function checkRange(rule, value, callback) {
  setTimeout(function () {
    if (rule.required && (isEmpty(value) || value.length !== 2)) {
      return callback(new Error(rule.message))
    }
    callback()
  }, 200)
}

export function checkObj(rule, value, callback) {
  setTimeout(function () {
    if (rule.required && isEmpty(value)) {
      return callback(new Error(rule.message))
    }
    callback()
  }, 200)
}

export function checkNumber(rule, value, callback) {
  setTimeout(function () {
    if (rule.required && isEmpty(value)) {
      return callback(new Error(rule.message))
    }
    if (value) {
      let reg = /^[1-9]\d*$/
      if (reg.test(value) === false) {
        return callback(new Error('只能输入整数'))
      }
    }
    callback()
  }, 200)
}

/**
 * 时间格式化
 * @param value date
 * @param fmt 格式
 * @returns {*}
 */
export function formatDate(value, fmt) {
  let getDate = value
  let o = {
    'M+': getDate.getMonth() + 1,
    'd+': getDate.getDate(),
    'h+': getDate.getHours(),
    'm+': getDate.getMinutes(),
    's+': getDate.getSeconds(),
    'q+': Math.floor((getDate.getMonth() + 3) / 3),
    S: getDate.getMilliseconds()
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (getDate.getFullYear() + '').substr(4 - RegExp.$1.length))
  }
  for (let k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
    }
  }
  return fmt
}

/**
 * 获取某天所在月的天数
 * @param value 时间
 * @returns 月天数
 */
export function getMonthDayNum(value) {
  let year = value.getFullYear()
  let month = value.getMonth()
  let monthStartDate = new Date(year, month, 1)
  let monthEndDate = new Date(year, month + 1, 1)
  let days = (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24)
  return days
}

/**
 * 获取某天的开始时间
 * @param value 某天
 * @returns 某天的开始时间
 */
export function getStartTimeOfDate(value) {
  let year = value.getFullYear()
  let month = value.getMonth()
  let dateOfMonth = value.getDate()
  return new Date(year, month, dateOfMonth, 0, 0, 0)
}

/**
 * 获取某天的结束时间
 * @param value 某天
 * @returns 某天的结束时间
 */
export function getEndTimeOfDate(value) {
  let year = value.getFullYear()
  let month = value.getMonth()
  let dateOfMonth = value.getDate()
  return new Date(year, month, dateOfMonth, 23, 59, 59)
}

/**
 * 获取某天所在周的开始时间
 * @param value 某天
 * @returns 周开始时间
 */
export function getStartTimeOfWeek(value) {
  let year = value.getFullYear()
  let month = value.getMonth()
  let dateOfMonth = value.getDate()
  let dateOfWeeb = value.getDay()
  return new Date(year, month, dateOfMonth - dateOfWeeb + 1, 0, 0, 0)
}

/**
 * 获取某天所在周的结束时间
 * @param value 某天
 * @returns 周结束时间
 */
export function getEndTimeOfWeek(value) {
  let year = value.getFullYear()
  let month = value.getMonth()
  let dateOfMonth = value.getDate()
  let dateOfWeeb = value.getDay()
  return new Date(year, month, dateOfMonth + 7 - dateOfWeeb, 23, 59, 59)
}

/**
 * 获取某天所在月的开始时间
 * @param value 某天
 * @returns 月开始时间
 */
export function getStartTimeOfMonth(value) {
  let year = value.getFullYear()
  let month = value.getMonth()
  return new Date(year, month, 1, 0, 0, 0)
}

/**
 * 获取某天所在月的结束时间
 * @param value 某天
 * @returns 月结束时间
 */
export function getEndTimeOfMonth(value) {
  let year = value.getFullYear()
  let month = value.getMonth()
  return new Date(year, month, getMonthDayNum(value), 23, 59, 59)
}

/**
 * 替换字符串
 * 如   stringFormat('a{}b{}c', 1, 2) = a1b2c
 * @param formatted
 * @param args
 * @returns {*}
 */
export function stringFormat(formatted, args) {
  for (let i = 0; i < args.length; i++) {
    let regexp = new RegExp('\\{' + i + '\\}', 'gi')
    formatted = formatted.replace(regexp, args[i])
  }
  return formatted
}
